package com.shakespace.artofandroid.chapter12bitmapandcache

import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import java.io.FileDescriptor

class ImageResizer {
    /**
     * 从资源文件中获取相应的图片
     *
     * @param res
     * @param resId
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    fun decodeSampleBitmapFromResource(
        res: Resources?,
        resId: Int,
        reqWidth: Int,
        reqHeight: Int
    ): Bitmap {
        val options = BitmapFactory.Options()
        //设置只加载宽高标志位
        options.inJustDecodeBounds = true
        //加载原始图片宽高到Options中
        BitmapFactory.decodeResource(res, resId, options)
        //计算采样率，通过所需宽高和原始图片宽高
        options.inSampleSize = calculateSampleSize(reqWidth, reqHeight, options)
        //还原并再次加载图片
        options.inJustDecodeBounds = false
        return BitmapFactory.decodeResource(res, resId, options)
    }

    /**
     * 从文件描述符中获取相应的图片
     *
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    fun decodeSampleBitmapFromFileDescriptor(
        fd: FileDescriptor?,
        reqWidth: Int,
        reqHeight: Int
    ): Bitmap {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeFileDescriptor(fd, null, options)
        options.inSampleSize = calculateSampleSize(reqWidth, reqHeight, options)
        options.inJustDecodeBounds = false
        return BitmapFactory.decodeFileDescriptor(fd, null, options)
    }

    companion object {
        //计算采样率
        fun calculateSampleSize(
            reqWidth: Int,
            reqHeight: Int,
            options: BitmapFactory.Options
        ): Int {
            //如果传入0参数，则将采样率设成1，即不压缩
            if (reqWidth == 0 || reqHeight == 0) {
                return 1
            }
            var inSampleSize = 1
            var width = options.outWidth
            var height = options.outHeight

            //当所需宽高比实际宽高小时才进行压缩
            if (reqWidth < width && reqHeight < height) {
                width = width shr 1
                var halfWidth = width
                height = height shr 1
                var halfHeight = height
                //保证压缩后的宽高不能小于所需宽高
                while (reqWidth <= halfWidth && reqHeight <= halfHeight) {
                    inSampleSize = inSampleSize shl 1
                    halfWidth /= inSampleSize
                    halfHeight /= inSampleSize
                }
            }
            return inSampleSize
        }
    }
}